home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / jpegagasrc / jpegaga / encodeham8.asm < prev    next >
Assembly Source File  |  1995-11-08  |  11KB  |  267 lines

  1. ; jpegAGA 2.0 utility function written by Günther Röhrich
  2. ; this code is Public Domain and may be used with other programs
  3.  
  4. ; this version is for 68020+ processors only
  5. ; it is is called from C:
  6. ; EncodeHAM8(char *orig, char *yham, int xsize);
  7. ; orig        = original row in RGBRGB... format
  8. ; yham        = row in HAM8 chunky format
  9. ; xsize       = size of row in pixels
  10.  
  11.  
  12.  MACHINE MC68020
  13.  
  14. ;NOTE: GCC stores all data as 32 bit at subroutine calls!
  15.  
  16. orig         EQU 44  ;pointer to original row (RGBRGB)
  17. yham         EQU 48  ;pointer to actual row (HAM)
  18. xsize        EQU 52  ;number of pixels
  19.  
  20.     
  21.         XREF _Mult_Table  ;address of multiplication table
  22.         XDEF _EncodeHAM8  ;entry point for function
  23.         XREF _ColorCache ;an 256K array
  24.         XREF _ColorTable ;an array with 64 colors
  25.  
  26. *       XDEF _blue_left ;only for debugging purposes
  27. *       XDEF _search_finish ;only for debugging
  28. *       XDEF _MaxError
  29. *       XDEF _MaxErrorPos 
  30. *       XDEF _hit       ;only for debugging
  31. *       XDEF _t1        ;only for debugging        
  32.  
  33.                dseg
  34.  
  35.  cnop 0,4
  36. _blue_left:      dc.b 0  ;this order is better for HAM-encoding
  37. _red_left:       dc.b 0
  38. _green_left:     dc.b 0,0 ;additional dummy-value for faster longword access
  39.  
  40.  cnop 0,2
  41. _offset_orig:   dc.w 0
  42. _offset_ham:    dc.w 0
  43. _CacheOffset    dc.l 0
  44. _colcount       dc.w 2
  45.  
  46.         cseg
  47.  
  48. ;register usage:   D0 = general purpose register
  49. ;                  D1 = contains afterwards the error
  50. ;                  D2 = orig_blue
  51. ;                  D3 = orig_red
  52. ;                  D4 = orig_green
  53. ;                  D5 = color that should be set
  54. ;                  D6 = offset to actual pixel (HAM)
  55. ;                  D7 = offset for color table / (0,1,2) at HAM
  56. ;                  A0 = best color so far (color+1)*3
  57. ;                  A1 = pointer to multiplication table
  58. ;                  A2 = pointer to color table / to _blue_left
  59. ;                  A3 = smallest error that has been reached so far
  60. ;                  A4 = used by the Aztec assembler (small data model)
  61. ;                  A5 = pointer to original row (RGBRGB...)
  62. ;                  A6 = pointer to the actual row (HAM)
  63.  
  64.  
  65.  
  66. ;computing the difference of color values is done with signed 8 bit
  67. ;arithmetic 
  68.  
  69. ;the maximum error value is 63^2+63^2+63^2=11907
  70. ;the summation has to be done therefore with 16 bits
  71.  
  72.  
  73. ;Initializing
  74. _EncodeHAM8:    movem.l D2-D7/A2-A3/A5/A6,-(A7)  ;store registers
  75.                 lea     _blue_left,A0      ;load start of left colors
  76.                 lea     _ColorTable,A2
  77.                 move.l  (A2),(A0)          ;initialize left colors
  78.                 moveq.l #0,D6              ;initialize ham offset  
  79.                 move.l  yham(sp),A6
  80.                 move.l  orig(sp),A5                           
  81.                 lea     _Mult_Table,A1
  82.                 lea     255*2(A1),A1              
  83. search_begin:   move.b  (A5)+,D3           ;load registers with original colors
  84.                 lsr.b   #2,D3
  85.                 move.b  (A5)+,D4           ;for faster access
  86.                 lsr.b   #2,D4
  87.                 move.b  (A5)+,D2
  88.                 lsr.b   #2,D2
  89.                 move.w  #15000,A3          ;dummy-value for minimum error so far
  90.                 lea     _ColorTable,A2
  91.                 moveq.l #0,D7              ;initialize offset for color table
  92.  
  93. ;find out if the new pixel has the same color as the previous one
  94.  
  95.                 lea      _blue_left,A0
  96.                 cmp.b    (A0),D2
  97.                 bne.s    search_cont
  98.                 cmp.b    1(A0),D3
  99.                 bne.s    search_cont
  100.                 cmp.b    2(A0),D4
  101.                 bne.s    search_cont
  102.  
  103. ;the new pixel has the same color, let's do a special encoding
  104.  
  105.                 move.w   _colcount,D7
  106.                 move.b   0(A0,D7.w),D5      
  107.                 subq.w   #1,_colcount
  108.                 bpl.s    ham6_9
  109.                 move.w  #2,_colcount
  110.                 bra.s    ham6_9
  111.                       
  112.  
  113.  
  114. ;First take a look if we have the value already in the cache
  115. search_cont:    moveq.l  #0,D0
  116.                 moveq.l  #0,D1             
  117.                 move.b   D3,D0             ;compute the cache offset
  118.                 lsl.l    #6,D0
  119.                 or.b     D4,D0
  120.                 lsl.l    #6,D0
  121.                 or.b     D2,D0             ;now we have the offset in D0
  122.                 movea.l  _ColorCache,A0    ;load start address of the cache
  123.                 move.b   0(A0,D0.l),D1     ;take the value from the cache
  124.                 bne     _hit               ;jump if we have a cache hit
  125.                 
  126.                 move.l   D0,_CacheOffset   ;store the offset to avoid recomputing it
  127.                 move.l   #3,A0             ;dummy-value for best colornumber so far
  128.                                            ; (3 means color 0)
  129.  
  130. search_start:    bsr      _compute_error
  131.                 cmp.w    D1,A3              ;A3 <= D1 ?
  132.                 bls.s    search4
  133.                 move.w   D1,A3              ;D1 is smaller than A3, store it
  134.                 move.w   D7,A0              ;store color number     
  135.                 tst.w    D1                 ;do we have the correct color ?
  136.                 beq      search5            ;then finish immediately
  137. search4:        cmp.w    #64*3,D7            ;have we reached highest colornum ?
  138.                 bne.s    search_start       ;no, then once again                   
  139.                                         
  140. ;A0 contains now (colornumber+1)*3
  141. ;A3 contains the error for that colornumber
  142.  
  143. _t1:            move.w   A0,D0        
  144.                 movea.l  _ColorCache,A2
  145.                 move.l   _CacheOffset,D1
  146.                 move.b   D0,0(A2,D1.l)      ;store the value in the cache                
  147.                 lea      _blue_left,A2      ;restore A2
  148.  
  149. ;compute the error when using modify mode
  150.  
  151. start_ham6:     move.b   D2,D0              ;load orig_blue
  152.                 moveq.l  #0,D7              ;assume blue should be changed
  153.                 move.b   D2,D5              ;store value to change
  154.                 sub.b    _blue_left,D0      ;D0=D0-_blue_left
  155.                 bpl.s    ham6_1
  156.                 neg.b    D0                 ;make result positive
  157. ham6_1:         move.b   D0,D1              ;store maximum error so far
  158.                 move.b   D3,D0              ;load orig_red
  159.                 sub.b    _red_left,D0       ;D0=D0-_red_left
  160.                 bpl.s    ham6_2
  161.                 neg.b    D0              
  162. ham6_2:         cmp.b    D0,D1              ;check D1-D0
  163.                 bge.s    ham6_3             ;jump if D1>=D0
  164.                 move.b   D0,D1              ;store new maximum error
  165.                 moveq.l  #1,D7              ;assume red should be changed
  166.                 move.b   D3,D5              ;store value to change
  167. ham6_3:         move.b   D4,D0              ;load orig_green
  168.                 sub.b    _green_left,D0     ;D0=D0-_green_left
  169.                 bpl.s    ham6_4
  170.                 neg.b    D0
  171. ham6_4:         cmp.b    D0,D1
  172.                 bge.s    ham6_5
  173.                 move.b   D0,D1              ;store maximum error
  174.                 moveq.l  #2,D7              ;green should be changed
  175.                 move.b   D4,D5              ;store value to change
  176. ham6_5:         lea      _blue_left,A2      
  177.                 move.b   D5,0(A2,D7.W)      ;perform change
  178.  
  179. ham_error:      moveq.l  #0,D1
  180.                 moveq.l  #0,D0
  181.                 move.b   D2,D0              ;load blue_origin
  182.                 sub.b    (A2)+,D0           ;D0 = blue_color - blue_origin
  183.                 ext.w    D0
  184.                 add.w    0(A1,D0.W*2),D1
  185.                 move.b   D3,D0              ;load red_origin
  186.                 sub.b    (A2)+,D0           ;D0 = red_color - red_origin 
  187.                 ext.w    D0
  188.                 add.w    0(A1,D0.W*2),D1
  189.                 move.b   D4,D0              ;load green_origin
  190.                 sub.b    (A2)+,D0           ;D0 = green_color - green_origin
  191.                 ext.w    D0
  192.                 add.w    0(A1,D0.W*2),D1
  193.  
  194.                 cmpa.w   D1,A3              ;check what error is smaller
  195.                 bls.s    _search_finish     ;jump if colortable is better
  196. ham6_9:         add.b    #1,D7              ;needed to get correct code
  197.                 lsl.b    #6,D7              ;HAM8-adjust                               
  198.                 or.b     D5,D7
  199.                 move.b   D7,(A6,D6.W)       ;store code in bitmap
  200.  
  201.                 addq.w   #1,D6              ;increase _offset_ham
  202.                 cmp.l    xsize(sp),D6       ;end of column ?
  203.                 bne      search_begin
  204.                 bra.s    search_end
  205.                 
  206. _search_finish: move.w   A0,D0
  207.                 lea      _ColorTable,A2
  208.                 lea      -3(A2,D0.W),A3     ;load A3 with pointer to colors
  209.                 divu     #3,D0
  210.                 subq.w   #1,D0
  211.                 move.b   D0,0(A6,D6.W)      ;store colornumber in bitmap
  212.                 lea      _blue_left,A2
  213.                 move.l   (A3),(A2)
  214.                 addq.w   #1,D6              ;increase _offset_ham
  215.                 cmp.l    xsize(sp),D6       ;have we reached the end ?
  216.                 bne      search_begin
  217.  
  218. search_end:     movem.l  (A7)+,D2-D7/A2-A3/A5/A6  ;restore registers
  219.                 rts                         ;jump back to caller
  220.                 
  221.  
  222.  
  223. ;we jump here if we have reached error 0 by colortable only
  224. ;and there was not a cache hit
  225. search5:        move.w   A0,D0         
  226.                 movea.l  _ColorCache,A2
  227.                 move.l   _CacheOffset,D1
  228.                 move.b   D0,0(A2,D1.l)      ;store the value in the cache                
  229.                 bra.s    _search_finish
  230.  
  231.  
  232. ;we jump here if we have a cache hit
  233. ;D1 contains the best color number, but we have to compute the error
  234.  
  235. _hit:           subq.w   #3,D1              ;correct color number
  236.                 move.w   D1,D7
  237.                 bsr.s    _compute_error
  238.         move.w   D1,A3              ;D1 is smaller than A3, store it
  239.                 move.w   D7,A0              ;store color number     
  240.                 bra      start_ham6         ;continue with HAM encoding
  241.  
  242.  
  243. ;compute the error
  244.  
  245. _compute_error: moveq.l  #0,D1
  246.                 moveq.l  #0,D0             
  247.                 move.b   D2,D0              ;load blue_origin
  248.                 sub.b    0(A2,D7.W),D0      ;D0 = blue_color - blue_origin
  249.                 ext.w    D0                 ;extend result to word
  250.                 add.w    0(A1,D0.W*2),D1
  251.                 addq.w   #1,D7              ;advance color table offset
  252.                 move.b   D3,D0              ;load red_origin
  253.                 sub.b    0(A2,D7.W),D0      ;D0 = red_color - red_origin
  254.                 ext.w    D0
  255.                 add.w    0(A1,D0.W*2),D1
  256.                 addq.w   #1,D7              ;advance color table offset
  257.                 move.b   D4,D0              ;load green_origin
  258.                 sub.b    0(A2,D7.W),D0      ;D0 = green_color - green_origin
  259.                 ext.w    D0
  260.                 add.w    0(A1,D0.W*2),D1  ;D1 = D1 + D0*D0
  261.                 addq.w   #1,D7              ;advance color table offset
  262.         rts
  263.  
  264.                 
  265.  
  266.  
  267.